package com.cz.fra.android.logic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import com.cz.fra.android.data.FishReport.ReportTable;
import com.cz.fra.android.entity.Report;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

public class ReportLogic {

	private static ReportLogic instance;
	
	private ContentResolver cr;

	private Context mContext;
	
	private ReportLogic(Context context) {
		mContext = context;
		cr = mContext.getContentResolver();
	}
	
	public static ReportLogic getInstance(Context context) {
		if (instance == null) {
			instance = new ReportLogic(context);
		}
		return instance;
	}
	
	public void insertReport(Report report){
		if (cr == null) {
			cr = mContext.getContentResolver();
		}
		Report temp = isReportInDB(report.getReportID());
		if (temp != null) {
			String where = ReportTable.REPORT_ID + "=" + "'"+temp.getReportID()+"'";
			cr.delete(ReportTable.CONTENT_URI, where, null);
		}
		cr.insert(ReportTable.CONTENT_URI, report.instanceToCV());
	}
	
	public synchronized void insertReports(ArrayList<Report> list) {
		if (cr == null) {
			cr = mContext.getContentResolver();
		}

		ArrayList<Report> distinctList = new ArrayList<Report>();
		int length = list.size();
		for(int i = 0; i < length; i++){
			Report r = list.get(i);
			if(isReportInDB(r.getReportID()) == null){
				distinctList.add(r);
			}
		}
		
		Log.e("insertReportList start", System.currentTimeMillis() + "");
		int distinctLength = distinctList.size();
		ContentValues[] values = new ContentValues[distinctLength];
		for (int i = 0; i < distinctLength; i++) {
			Report r = list.get(i);
			values[i] = r.instanceToCV();
		}
		if(values.length > 0){
			cr.bulkInsert(ReportTable.CONTENT_URI, values);
		}
		synchronized (list) {
			list.clear();
		}
		Log.e("insertReportList end", System.currentTimeMillis() + "");
	}
	
	public void updateReportCommentNum(int reportId){
		int commentNo = CommentLogic.getInstance(mContext).getCommentNum(reportId);
		Report report = getReportById(reportId);
		report.setCommentNo(commentNo);
		insertReport(report);
	}
	
	public ArrayList<Report> getReports(){
		if (cr == null) {
			cr = mContext.getContentResolver();
		}
		ArrayList<Report> arrayList = new ArrayList<Report>();
		Cursor cursor = cr.query(ReportTable.CONTENT_URI, null, null, null, null);
		if (cursor.moveToFirst()) {
			do {
				Report rp = new Report();
				rp.setReportID(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_ID)));
				rp.setTitle(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_TITLE)));
				rp.setDescription(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_DESCRIPTION)));
				rp.setLocations(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_LOCATIONS)));
				rp.setBaits(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_BAITS)));
				rp.setSpecies(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_SPECIES)));
				rp.setImgs(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_IMGS)));
				rp.setCommentNo(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_COMMENTNO)));
				rp.setCreatedBy(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_USER_ID)));
				rp.setUpdatedBy(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_USER_ID)));
				rp.setCreatedDate(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_CREATE_DATE)));
				rp.setUpdatedDate(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_UPDATE_DATE)));
				
				arrayList.add(rp);
				}while (cursor.moveToNext());
		}
		cursor.close();
		//Report need to implement Comparable interface in order to sort.
		Collections.sort(arrayList);
		return arrayList;
	}
	
	public Report getReportById(int reportId){
		if (cr == null) {
			cr = mContext.getContentResolver();
		}
		Cursor cursor = cr.query(ReportTable.CONTENT_URI, null, ReportTable.REPORT_ID+ "=" + "'" + reportId+ "'", null, null);
		Report report = new Report();
		if (cursor.moveToFirst()) {
			report.setReportID(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_ID)));
			report.setTitle(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_TITLE)));
			report.setDescription(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_DESCRIPTION)));
			report.setLocations(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_LOCATIONS)));
			report.setBaits(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_BAITS)));
			report.setSpecies(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_SPECIES)));
			report.setImgs(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_IMGS)));
			report.setCommentNo(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_COMMENTNO)));
			report.setCreatedBy(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_USER_ID)));
			report.setUpdatedBy(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_USER_ID)));
			report.setCreatedDate(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_CREATE_DATE)));
			report.setUpdatedDate(cursor.getString(cursor.getColumnIndex(ReportTable.REPORT_UPDATE_DATE)));
		}
		cursor.close();
		return report;
	}
	
	public Report isReportInDB(int reportId){
		Report report = null;
		Cursor cursor = cr.query(ReportTable.CONTENT_URI, null, ReportTable.REPORT_ID+ "=" + "'" + reportId + "'", null, null);
		if (cursor.moveToFirst()) {
			report = new Report();
			report.setReportID(cursor.getInt(cursor.getColumnIndex(ReportTable.REPORT_ID)));
		}
		if (cursor != null) {
			cursor.close();
		}
		return report;
	}

	public ArrayList<Report> insertNewReports(ArrayList<Report> newReportList) {
		ArrayList<Report> newList = new ArrayList<Report>();
		if (cr == null) {
			cr = mContext.getContentResolver();
		}
		for(Report report : newReportList){
			Report temp = isReportInDB(report.getReportID());
			if (temp != null) {
				String where = ReportTable.REPORT_ID + "=" + "'"+temp.getReportID()+"'";
				cr.delete(ReportTable.CONTENT_URI, where, null);
			}
			else{
				newList.add(report);
			}
			cr.insert(ReportTable.CONTENT_URI, report.instanceToCV());
		}
		return newList;
	}
}
